#define _GNU_SOURCE     /* To get defns of NI_MAXSERV and NI_MAXHOST */
#include <arpa/inet.h>  
#include <sys/socket.h>
#include <netdb.h>
#include <ifaddrs.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <linux/if_link.h>
#include <string.h>
#include <signal.h>
#include <sys/time.h>

#include "Msg.h"

#define COUNT_SEC 1
#define COUNT_USEC 0

/* 产生精确到微秒的当前时间字符串 */
/* yyyy-mm-dd hh:mm:ss:uuuuuu 共27字节 */
char* Time_Display(void)
{
	static char str_time[32] = {0};
	memset(str_time, 0 , sizeof(str_time));

	struct timeval tv = {0};
	struct tm p_tm = {0};
	/* gettimeofday 功能是得到当前时间和时区，分别写到tv和tz中，如果tz为NULL则不向tz写入 */
	gettimeofday(&tv, NULL);
	localtime_r(&tv.tv_sec, &p_tm);	//localtime_r 相比localtime线程安全
	sprintf(str_time, "%4d-%02d-%02d %02d:%02d:%02d.%6.6d", 
	p_tm.tm_year + 1900,
	p_tm.tm_mon + 1,
	p_tm.tm_mday,
	p_tm.tm_hour,
	p_tm.tm_min,
	p_tm.tm_sec,
	(int)tv.tv_usec);

	return str_time;
}


static void Info_Get(int sig)
{
    struct ifaddrs *ifaddr, *ifa;
    int family, s, n;
    char host[NI_MAXHOST];

    if (getifaddrs(&ifaddr) == -1) {
        perror("getifaddrs");
        exit(EXIT_FAILURE);
    }

    /* Walk through linked list, maintaining head pointer so we
    can free list later */

    if_index = 0;
    for (ifa = ifaddr, n = 0; ifa != NULL; ifa = ifa->ifa_next, n++) {
        if (ifa->ifa_addr == NULL)
        continue;

        family = ifa->ifa_addr->sa_family;

        /* Display interface name and family (including symbolic
        form of the latter for the common families) */
#if 0
        printf("%-8s %s (%d)\n",
               ifa->ifa_name,
               (family == AF_PACKET) ? "AF_PACKET" :
               (family == AF_INET) ? "AF_INET" :
               (family == AF_INET6) ? "AF_INET6" : "???",
               family);
#endif

        /* For an AF_INET* interface address, display the address */

        if (family == AF_INET || family == AF_INET6) {
            s = getnameinfo(ifa->ifa_addr,
                            (family == AF_INET) ? sizeof(struct sockaddr_in) :
                            sizeof(struct sockaddr_in6),
                            host, NI_MAXHOST,
                            NULL, 0, NI_NUMERICHOST);
            if (s != 0) {
                printf("getnameinfo() failed: %s\n", gai_strerror(s));
                exit(EXIT_FAILURE);
            }

            //printf("\t\taddress: <%s>\n", host);

        } else if (family == AF_PACKET && ifa->ifa_data != NULL) {

            struct rtnl_link_stats *stats = ifa->ifa_data;
#if 0
            printf("\t\ttx_packets = %10u; rx_packets = %10u\n"
                   "\t\ttx_bytes   = %10u; rx_bytes   = %10u\n",
                   stats->tx_packets, stats->rx_packets,
                   stats->tx_bytes, stats->rx_bytes);
                   //g_tx_packets = stats->tx_packets;
#endif
    /******将接口信息存在全局变量中********/
    sprintf(szMsg[if_index].g_if_name, "Interface %d : %s", n, ifa->ifa_name);
    sprintf(szMsg[if_index].g_tx_packets, "\ttx_packets = %-10u", stats->tx_packets);
    sprintf(szMsg[if_index].g_rx_packets, "\trx_packets = %-10u", stats->rx_packets);
    sprintf(szMsg[if_index].g_tx_bytes, "\ttx_bytes = %-10u", stats->tx_bytes);
    sprintf(szMsg[if_index].g_rx_bytes, "\trx_bytes = %-10u", stats->rx_bytes);
    sprintf(g_cur_time, "Current Time:%s\n", Time_Display());
    if_index++;
        }
    }

    freeifaddrs(ifaddr);
    
    //exit(EXIT_SUCCESS);
}

 
/*Initialize timer*/
static void Init_timer(struct itimerval *tick)
{
    int ret;
    memset(tick, 0, sizeof(struct itimerval));
 
    /*initialize it_value*/
    tick->it_value.tv_sec = COUNT_SEC;      //第一次等待COUNT_SEC时间后开始执行
    tick->it_value.tv_usec = COUNT_USEC;
 
    /*initialize it_interval*/
    tick->it_interval.tv_sec = COUNT_SEC;     //每COUNT_SEC 时间执行一次
    tick->it_interval.tv_usec = COUNT_USEC;
 
    return;
}
 


int main(int argc, const char * argv [])
{
    int ret = 0;
    struct itimerval tick;
    
    signal(SIGALRM, Info_Get);
    
    Init_timer(&tick);
    
    ret = setitimer(ITIMER_REAL, &tick, NULL);
    if(ret < 0)
    {
        printf("setitimer failed!\n");
        return -1;
    }
    while(1)
    {
        Info_Display();
    }

    return 0;
}
